package org.sfx.rich

import javafx.beans.value.ChangeListener
import javafx.beans.value.ObservableValue

case class RichObservableValue[T](
    ref: {
      def addListener(listener: ChangeListener[_ >: T])
      def removeListener(listener: ChangeListener[_ >: T])
    }) {
  def addChangeListener[U >: T](f: (ObservableValue[_ <: U], U, U) => Unit): Unit = {
    ref.addListener(new ChangeListener[U] {
      def changed(observableValue: ObservableValue[_ <: U], oldValue: U, newValue: U): Unit = {
        f(observableValue, oldValue, newValue)
      }
    })
  }

  def addFirstChangeListener[U >: T](f: (ObservableValue[_ <: U], U, U) => Unit): Unit = {
    val listener = new ChangeListener[U] {
      def changed(observableValue: ObservableValue[_ <: U], oldValue: U, newValue: U): Unit = {
        ref.removeListener(this)
        f(observableValue, oldValue, newValue)
      }
    }
    ref.addListener(listener)
  }
}
